﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Text;

namespace AMM.CustomClassLibrary {
    public static class MethodHelper {
        public static string ExtractExceptionMessage(Exception ex = null) {
            if (ex == null) { return string.Empty; }

            StringBuilder sb = new StringBuilder();
            Action<Exception> act = null;
            act = e => {
                sb.AppendFormat("Exception Source: {0}", e.Source);
                sb.AppendLine();
                sb.AppendFormat("Exception Message: {0}", e.Message);
                if (e.InnerException != null) {
                    act.Invoke(e.InnerException);
                }
            };
            act.Invoke(ex);

            return sb.ToString();
        }

        public static string GetFileSize(long fileSize) {
            string size = string.Empty;
            double threePow = Math.Pow(1024, 3);
            double twoPow = Math.Pow(1024, 2);

            if (fileSize >= threePow) {
                size = Math.Round(fileSize / threePow * 1000 / 1000, 2) + "G";
            }
            if (fileSize >= twoPow && fileSize < threePow) {
                size = Math.Round(fileSize / twoPow * 1000 / 1000, 2) + "M";
            }
            if (fileSize >= 1024 && fileSize < twoPow) {
                size = Math.Round((double)(fileSize / 1024 * 1000 / 1000), 2) + "K";
            }
            if (fileSize >= 0 && fileSize < 1024) {
                size = Math.Round((double)fileSize, 2) + "B";
            }
            return size;
        }

        #region Enum

        /// <summary>
        /// 获取指定枚举中，对应枚举的 Description 的 Attribute 的值，
        /// 与枚举的索引组成匿名对象加入到 List 中返回，new { Text = text, Value = value }
        /// </summary>
        /// <param name="enumType">指定枚举的 Type</param>
        /// <returns>List</returns>
        public static List<object> GetEnumDescriptionToList(Type enumType, bool isAddedDefault = false) {
            if (enumType.IsEnum) {
                int value;
                string text;
                object[] attr;
                List<object> resultList = new List<object>();
                Type descriptionType = typeof(DescriptionAttribute);
                if (isAddedDefault) {
                    resultList.Insert(0, new { Text = "", Value = -1 });
                }

                foreach (FieldInfo fi in enumType.GetFields()) {
                    if (fi.FieldType.IsEnum) {
                        attr = fi.GetCustomAttributes(descriptionType, true);
                        if (attr.Length == 0) {
                            throw new FormatException("enum 类型错误");
                        }
                        text = attr.Length > 0 ? ((DescriptionAttribute)attr[0]).Description : fi.Name;
                        value = (int)enumType.InvokeMember(fi.Name, BindingFlags.GetField, null, null, null);
                        resultList.Add(new { Text = text, Value = value });
                    }
                }
                return resultList;
            }
            else {
                throw new ArgumentException("必须是 enum 类型");
            }
        }

        /// <summary>
        /// 根据 value 读取指定枚举中的 Description 的 Attribute 的值，
        /// </summary>
        /// <param name="enumType">指定枚举的 Type</param>
        /// <param name="value">值</param>
        /// <returns>string</returns>
        public static string GetEnumsDescription(Type enumType, int value) {
            if (enumType.IsEnum) {
                int val;
                string text;
                object[] attr;
                Type descriptionType = typeof(DescriptionAttribute);

                foreach (FieldInfo fi in enumType.GetFields()) {
                    if (fi.FieldType.IsEnum) {
                        attr = fi.GetCustomAttributes(descriptionType, true);
                        if (attr.Length == 0) {
                            throw new FormatException("enum 类型错误");
                        }
                        text = attr.Length > 0 ? ((DescriptionAttribute)attr[0]).Description : fi.Name;
                        val = (int)enumType.InvokeMember(fi.Name, BindingFlags.GetField, null, null, null);
                        if (value == val) {
                            return text;
                        }
                    }
                }
                return string.Empty;
            }
            else {
                throw new ArgumentException("必须是 enum 类型");
            }
        }

        /// <summary>
        /// 通过枚举的名称返回枚举
        /// </summary>
        /// <typeparam name="T">枚举</typeparam>
        /// <param name="name">枚举的名称</param>
        /// <returns>T</returns>
        public static T GetEnumByName<T>(string name) {
            Type orderStatusType = typeof(T);
            if (orderStatusType.IsEnum) {
                var result = Enum.Parse(orderStatusType, name, true);
                if (Enum.IsDefined(orderStatusType, result)) {
                    return (T)result;
                }
                else {
                    throw new IndexOutOfRangeException("未找到指定信息");
                }
            }
            else {
                throw new ArgumentException("必须是 enum 类型");
            }
        }

        /// <summary>
        /// 通过枚举返字符串
        /// </summary>
        /// <typeparam name="T">枚举</typeparam>
        /// <param name="enumType">枚举</param>
        /// <returns>string</returns>
        public static string GetNameByEnum<T>(T enumType) {
            if (typeof(T).IsEnum) {
                return Enum.GetName(typeof(T), enumType);
            }
            else {
                throw new ArgumentException("必须是 enum 类型");
            }
        }

        #endregion

    }
}
